#!/usr/bin/python3
import socket
import threading
import base
import richiesta
import rete
import config
import websocket
import queue
from gi.repository import Gtk

#classe principale; questa classe è il vero e proprio server
class ServerThreaded:
    #costruttore; l'unico attributo richiesto è la porta ma quella standard va più che bene
    def __init__(self,porta=8080,fakeQueue=None):
        #porta che permette la connessione al socket da parte del client
        self.porta = porta
        self.fakeQueue = fakeQueue
        #questo è il socket
        self.server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        #questo attributo contiene l'indirizzo ip del server
        #che viene riconosciuto automaticamente del metodo
        #if serverIp is None:
        serverIp = socket.gethostname()
        self.serverIp = serverIp
        print("%(ip)s:%(port)s, %(cls)s" % {"ip": self.serverIp, "port": porta, "cls":self.__class__.__name__})
        #questa è la cartella root ossia la cartella
        #base che il server condivide
        self.root = "./root/"
        visual = threading.Thread(target=Vedigtk,args=[self.fakeQueue], name="GTK")
        visual.daemon=True
        visual.start()
    
    #questo metodo attiva il ciclo principale del server
    #e per ogni richiesta di connessione attiva un nuovo thread
    #richiede come parametri la dimensione del pacchetto (che può essere cambiata)
    #e il numero massimo di connessioni simultanee che è meglio lasciare così
    def ascolta(self, connessioni = 3):
        #imposta l'indirizzo ip del server e la porta passandolo
        #come una tupla
        connessione = -1
        self.contatore = 0
        self.server.bind(("", self.porta))
        #imposta il numero massimo di connessioni accettabili simultaneamente
        self.server.listen(connessioni)
        qu = queue.Queue()
        #thr = threading.Thread(target = richiesta.threadGestore,args=[qu],name="Gestore")
        #thr.daemon = True
        #thr.start()
        #questo è il ciclo infinito ossia il cuore del server
        try:
            while True:
                #questa riga attende una richiesta di connessione
                connessione, indirizzo = self.server.accept()
                print(str(connessione.fileno())+": apertura")
                #dopo che la connessione è stata accettata viene creato un nuovo
                #thread che gestisce la connessione appena accettata
                req = richiesta.Richiesta(connessione)
                thr = threading.Thread(target=rete.threadBloccante,args=[req, richiesta.recv,self.fakeQueue],name="Gestione HTTP, socket "+str(connessione.fileno()))
                #questo attributo permette di uccidere il thread quando viene ucciso il processo
                #padre ossia questo
                thr.daemon = True
                #dopo aver creato il thread viene lanciato
                thr.start()
        except KeyboardInterrupt as e:
            print("\n")
            
            rete.chiudi(self.server)
            
class Vedigtk :
    def aggiornaLista(self,src):
        lista = ""
        for th in threading.enumerate():
            lista += str(th) + "\n"
        self.tw.get_buffer().set_text(lista)
    def send(self,src):
        conn = int(self.connNum.get_value())
        buf = self.payload.get_buffer()
        pay =buf.get_text(buf.get_start_iter(),buf.get_end_iter(),True)
        fakeMesg = base.FakeMessage(conn,eval(pay))
        self.fakeQueue.put(fakeMesg)
        print("-->mandato")
    def __init__(self,fakeQueue):
        self.fakeQueue = fakeQueue
        Gtk.init()
        w = Gtk.Window()
        w.set_size_request(500,200)
        vb = Gtk.VBox(5)
        vb.set_homogeneous(False)
        w.add(vb)
        sw = Gtk.ScrolledWindow()
        self.tw= t = Gtk.TextView()
        t.set_editable(False)
        sw.add(t)
        vb.pack_start(sw,True,True,0)
        butt = Gtk.Button(label="Aggiorna")
        butt.connect("clicked", self.aggiornaLista)
        vb.pack_start(butt,False,False,0)
        self.connNum= Gtk.SpinButton()
        self.connNum.set_increments(1,1)
        self.connNum.set_range(0,200)
        vb.pack_start(self.connNum,False,False,0)
        self.payload= Gtk.TextView()
        sw2 = Gtk.ScrolledWindow()
        sw2.add(self.payload)
        vb.pack_start(sw2,True,True,0)
        butt2 = Gtk.Button(label="Invia")
        butt2.connect("clicked", self.send)
        vb.pack_start(butt2,False,False,0)
        self.aggiornaLista(None)
        w.show_all()
        Gtk.main()
#config.valoriServer = config.loadDir("./",hostName="config")
#s= Serverino(porta=int(config.valoriServer['SERVER']['Port']))
#s.ascolta()

